#include "pch.h"
#include "WaterEffect.h"
#include "RendererEngine.h"
#include "ReflectionEffect.h"
namespace mini
{
	CWaterEffect::CWaterEffect()
	{
		mWaterInfo.y = 0.01f;
	}

	CWaterEffect::~CWaterEffect()
	{
		SafeRelease(mpReflectionActor);
		SafeRelease(mpRefractionActor);
	}

	void CWaterEffect::updateFrame(float fDeltaTime)
	{
		mTranslation += 0.0005f;
		if (mTranslation > 1.0f)
		{
			mTranslation -= 1.0f;
		}
		mWaterInfo.x = mTranslation;
		if (nullptr != mpReflectionActor)
		{
			auto pCamera = mpReflectionActor->getCamera();
			auto matrix = pCamera->getViewMatrix();
			CMatrix refMx;
			D3DXMatrixTranspose(&refMx, &matrix);
			for (auto item : mpMeshUnits)
			{
				auto pMaterialUnit = item->getMaterialUnit();
				if (nullptr != pMaterialUnit)
				{
					pMaterialUnit->updateVSConstBuffer(5, &refMx);	
					pMaterialUnit->updatePSConstBuffer("WaterBuffer", &mWaterInfo);
				}
			}
		}
	}

	void CWaterEffect::initReflection(CCamera* pCamera)
	{
		SafeRelease(mpReflectionActor);
		CPoint3F eye(&pCamera->getEye().x);
		eye.y = -eye.y + mHeight * 2;
		CPoint3F lookat(eye.x, eye.y, eye.z + 1);
		mpReflectionActor = new CReflectionEffect;
		mpReflectionActor->setMaterial("resource/Material/Reflec.ma");
		mpReflectionActor->buildRefCamera(eye, lookat);
		GEngine->getCurrentScene()->addActor(mpReflectionActor);

		auto pMaterialUnit = mpReflectionActor->getMaterialUnit();
		if (nullptr != pMaterialUnit)
		{
			for (auto item : mpMeshUnits)
			{
				auto pUnit = item->getMaterialUnit();
				pUnit->setTexture(mpReflectionActor->getRenderTexture(), 1);
			}
		}
	}

	void CWaterEffect::initRefraction(CCamera* pCamera)
	{
		SafeRelease(mpRefractionActor);
		mpRefractionActor = new CRefractionEffect;
		mpRefractionActor->setMaterial("resource/Material/Refraction.ma");
		mpRefractionActor->buildRefCamera(&pCamera->getEye().x, &pCamera->getLookAt().x);
		mpRefractionActor->setClipPlane(CPoint4F(0.0f, -1.0f, 0.0f, mHeight + 0.1f));
		GEngine->getCurrentScene()->addActor(mpRefractionActor);
		
		auto pMaterialUnit = mpRefractionActor->getMaterialUnit();
		if (nullptr != pMaterialUnit)
		{
			for (auto item : mpMeshUnits)
			{
				auto pUnit = item->getMaterialUnit();
				pUnit->setTexture(mpRefractionActor->getRenderTexture(), 2);
			}
		}
	}

	void CWaterEffect::setWaterHeight(float fHeight)
	{
		mPosition.y = fHeight;
		setPosition(mPosition);
		mHeight = fHeight;
		if (nullptr != mpRefractionActor)
		{
			mpRefractionActor->setClipPlane(CPoint4F(0.0f, -1.0f, 0.0f, mHeight + 0.1f));
		}
	}

	float CWaterEffect::getWaterHeight()
	{
		return mHeight;
	}

}